home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The AGA Experience 3
/
AGA Experience Volume 3 (1997)(NFA - SAdENESS)[!].iso
/
software
/
utilities
/
graphics
/
raylab
/
source
/
ppm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-08-05
|
6KB
|
221 lines
/*
name: ppm.c
PPM 24-bit color picture support
--------------------------------
These routines enable image input/output in 24-bit PPM format.
I know very little about the PPM format (I have only looked at
one file to figure out the format), thus I guess RayLab is not
able to read all PPM files. RayLab supports the P6 PPM format
(binary 24-bit), and the 'max-value' for input files may range
from 1 to 255, presuming that each color-component (R,G, and B)
is one byte (three bytes/pixel).
This source-code is part of the RayLab 1.1 package, and it is provided
for your compiling pleasure. You may use it, change it, re-compile it
etc., as long as nobody else but you receive the changes/compilations
that you have made!
You may not use any part(s) of this source-code for your own productions
without the permission from the author of RayLab. Please read the legal
information found in the users documentation for RayLab for more details.
*/
#include <stdlib.h>
#include <string.h>
#include "defs.h"
#include "extern.h"
unsigned char ppmdata[parraysize*3];
long ppm_maxvalue;
/* ---------------------------------------------------------------------
WritePpmHeader()
--------------------------------------------------------------------- */
void WritePpmHeader(FILE *f,long width, long height)
{
fprintf(f,"P6"); fputc((char)10,f);
fprintf(f,"%ld %ld",width,height); fputc((char)10,f);
fprintf(f,"%d",255); fputc((char)10,f);
}
/* ---------------------------------------------------------------------
CleanupPpm()
--------------------------------------------------------------------- */
void CleanupPpm(FILE *f)
{
/* Not supported!! */
/* To make a proper Cleanup(), you need to be able to */
/* over-write the height value in the beginning of the */
/* file, which can be tricky as the PPM format uses ascii */
/* numbers, which occupies more or less space in the file */
/* depending on the magnitude of the number. */
}
/* ---------------------------------------------------------------------
WritePpmLine()
--------------------------------------------------------------------- */
void WritePpmLine(FILE *f, long width)
{
long i;
unsigned char *pixels;
pixels=ppmdata;
for(i=0;i<width;i++) {
*pixels++=pixelarray[i].r; /* Use order: r,g,b */
*pixels++=pixelarray[i].g;
*pixels++=pixelarray[i].b;
}
(void) fwrite((void *)ppmdata,sizeof(unsigned char),(size_t)(width*3),f);
}
/* ---------------------------------------------------------------------
ReadPpmHeader()
--------------------------------------------------------------------- */
void ReadPpmHeader(FILE *f, long *width, long *height)
{
int i, itmp;
long tmpwidth, tmpheight;
char buffer[20];
tmpwidth=tmpheight=*width=*height=-1L;
fread((void *)buffer,sizeof(char),(size_t)2,f);
buffer[2]=0;
if(strcmp(buffer,"P6")==0) {
buffer[0]=0;
itmp=fgetc(f);
while((itmp!=EOF)&&(ischar(itmp)==FALSE)) itmp=fgetc(f);
i=0;
while((itmp!=EOF)&&(ischar(itmp)==TRUE)) {
buffer[i]=(char)itmp;
itmp=fgetc(f);
i++;
}
if(itmp==EOF) {
fprintf(textoutput,"\nError: Premature end of PPM file\n");
}
else {
buffer[i]=0;
tmpwidth=atol(buffer);
buffer[0]=0;
itmp=fgetc(f);
while((itmp!=EOF)&&(ischar(itmp)==FALSE)) itmp=fgetc(f);
i=0;
while((itmp!=EOF)&&(ischar(itmp)==TRUE)) {
buffer[i]=(char)itmp;
itmp=fgetc(f);
i++;
}
if(itmp==EOF) {
fprintf(textoutput,"\nError: Premature end of PPM file\n");
}
else {
buffer[i]=0;
tmpheight=atol(buffer);
buffer[0]=0;
itmp=fgetc(f);
while((itmp!=EOF)&&(ischar(itmp)==FALSE)) itmp=fgetc(f);
i=0;
while((itmp!=EOF)&&(ischar(itmp)==TRUE)) {
buffer[i]=(char)itmp;
itmp=fgetc(f);
i++;
}
if(itmp==EOF) {
fprintf(textoutput,"\nError: Premature end of PPM file\n");
}
else {
buffer[i]=0;
ppm_maxvalue=atol(buffer);
if(ppm_maxvalue>255) {
fprintf(textoutput,"\nError: The PPM max-value must be less than 256\n");
tmpwidth=tmpheight=-1;
}
else {
while((itmp!=EOF)&&(itmp!=10)) itmp=fgetc(f);
}
}
}
}
if((itmp!=EOF)&&(tmpwidth>0)&&(tmpheight>0)) {
if(tmpwidth<=parraymaxpix) {
*width=tmpwidth;
*height=tmpheight;
}
else fprintf(textoutput,"\nError: Maximum width is %d\n",parraymaxpix);
}
}
else {
fprintf(textoutput,"\nError: Not recognized as a 'P6' PPM file\n");
}
}
/* ---------------------------------------------------------------------
ReadPpmImage()
--------------------------------------------------------------------- */
short ReadPpmImage(int *ImageNum, FILE *f, long width, long height)
{
short ImageType;
int i,j;
unsigned char *Ppmptr;
unsigned char *Bodyptr;
IMAGE24 *Image24;
ImageType=IMG_NONE;
if(Num24Images<maximages) {
Image24=(void *)malloc(sizeof(IMAGE24));
if(Image24!=NULL) {
Image24->XSize=width; Image24->YSize=height;
Image24->Interpolate=INTPOL_NONE;
Image24->Maptype=MAP_PLANAR;
Image24->Tile=TILE_TRUE;
Image24->Body=(unsigned char *)malloc((size_t)(width*height*3));
if(Image24->Body!=NULL) {
i=0;
Bodyptr=Image24->Body;
while(i<height) {
(void) fread(ppmdata,(size_t)1,(size_t)(3*width),f);
Ppmptr=ppmdata;
for(j=0;j<width;j++) {
*Bodyptr++=(unsigned char)((((int)*Ppmptr++)*255)/ppm_maxvalue);
*Bodyptr++=(unsigned char)((((int)*Ppmptr++)*255)/ppm_maxvalue);
*Bodyptr++=(unsigned char)((((int)*Ppmptr++)*255)/ppm_maxvalue);
}
i++;
}
*ImageNum=Num24Images;
Img24Array[Num24Images]=Image24;
Num24Images++;
ImageType=IMG_24BIT;
}
else {
free(Image24);
Image24=NULL;
}
}
}
else {
fprintf(textoutput,"\nError: Maximum amount of 24-bit images exceeded\n");
}
return(ImageType);
}